package com.zrq.gencode.jdbc;

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import com.zrq.gencode.cfg.JdbcCfg;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Connection;
import java.sql.SQLException;

/**
 * 数据库连接池管理类
 *
 * @author zhong
 * @date 2025年10月10日
 */
public class ConnectionPool {
	private static final Logger LOGGER = LoggerFactory.getLogger(ConnectionPool.class);

	private static HikariDataSource dataSource;

	static {
		try {
			initDataSource();
		} catch (Exception e) {
			LOGGER.error("初始化数据库连接池失败", e);
		}
	}

	/**
	 * 初始化数据库连接池
	 */
	private static void initDataSource() {
		HikariConfig config = getHikariConfig();

		// 添加更多MySQL特定配置
		config.addDataSourceProperty("cachePrepStmts", "true");
		config.addDataSourceProperty("prepStmtCacheSize", "250");
		config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
		config.addDataSourceProperty("useServerPrepStmts", "true");
		config.addDataSourceProperty("useLocalSessionState", "true");
		config.addDataSourceProperty("rewriteBatchedStatements", "true");
		config.addDataSourceProperty("cacheResultSetMetadata", "true");
		config.addDataSourceProperty("cacheServerConfiguration", "true");
		config.addDataSourceProperty("elideSetAutoCommits", "true");
		config.addDataSourceProperty("maintainTimeStats", "false");

		dataSource = new HikariDataSource(config);
		LOGGER.info("数据库连接池初始化完成，最大连接数: {}, 最小空闲连接数: {}", config.getMaximumPoolSize(),
		            config.getMinimumIdle());
	}

	private static HikariConfig getHikariConfig() {
		HikariConfig config = new HikariConfig();
		config.setJdbcUrl(JdbcCfg.getJdbcurl());
		config.setUsername(JdbcCfg.getJdbcusername());
		config.setPassword(JdbcCfg.getJdbcpassword());
		config.setDriverClassName(JdbcCfg.getJdbcDriver());

		// 连接池配置
		// 最大连接数
		config.setMaximumPoolSize(20);
		// 最小空闲连接数
		config.setMinimumIdle(5);
		// 连接超时时间(毫秒)
		config.setConnectionTimeout(30000);
		// 空闲连接超时时间(毫秒)
		config.setIdleTimeout(600000);
		// 连接最大存活时间(毫秒)
		config.setMaxLifetime(1800000);
		// 连接泄漏检测阈值(毫秒)
		config.setLeakDetectionThreshold(60000);

		// 数据库连接测试
		config.setConnectionTestQuery("SELECT 1");
		return config;
	}

	/**
	 * 获取数据库连接
	 *
	 * @return 数据库连接
	 * @throws SQLException SQL异常
	 */
	public static Connection getConnection() throws SQLException {
		if (dataSource == null) {
			throw new SQLException("数据库连接池未初始化");
		}
		Connection conn = dataSource.getConnection();
		if (conn == null) {
			throw new SQLException("无法从连接池获取数据库连接");
		}
		LOGGER.debug("从连接池获取数据库连接");
		return conn;
	}

	/**
	 * 测试数据库连接
	 *
	 * @return 连接是否成功
	 */
	public static boolean testConnection() {
		if (dataSource == null) {
			LOGGER.error("数据库连接池未初始化");
			return false;
		}

		try (Connection conn = dataSource.getConnection()) {
			boolean result = conn != null && !conn.isClosed();
			LOGGER.debug("数据库连接测试结果: {}", result ? "成功" : "失败");
			return result;
		} catch (SQLException e) {
			LOGGER.error("测试数据库连接失败", e);
			return false;
		}
	}

	/**
	 * 关闭数据库连接池
	 */
	public static void closeDataSource() {
		if (dataSource != null && !dataSource.isClosed()) {
			dataSource.close();
			LOGGER.info("数据库连接池已关闭");
		}
	}
}